package com.duojuhe.coremodule.tracking.service.impl;

import com.duojuhe.cache.SystemDictCache;
import com.duojuhe.common.annotation.DataScopeFilter;
import com.duojuhe.common.bean.UserTokenInfoVo;
import com.duojuhe.common.enums.SystemEnum;
import com.duojuhe.common.exception.base.DuoJuHeException;
import com.duojuhe.common.result.ErrorCodes;
import com.duojuhe.common.result.PageResult;
import com.duojuhe.common.result.ServiceResult;
import com.duojuhe.common.utils.idgenerator.UUIDUtils;
import com.duojuhe.common.utils.page.PageHelperUtil;
import com.duojuhe.coremodule.BaseService;
import com.duojuhe.coremodule.system.entity.SystemDict;
import com.duojuhe.coremodule.tracking.entity.TrackingCode;
import com.duojuhe.coremodule.tracking.entity.TrackingProduct;
import com.duojuhe.coremodule.tracking.entity.TrackingProductSupplier;
import com.duojuhe.coremodule.tracking.mapper.TrackingCodeMapper;
import com.duojuhe.coremodule.tracking.mapper.TrackingProductMapper;
import com.duojuhe.coremodule.tracking.mapper.TrackingProductSupplierMapper;
import com.duojuhe.coremodule.tracking.pojo.dto.trackingcode.*;
import com.duojuhe.coremodule.tracking.service.TrackingCodeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class TrackingCodeServiceImpl  extends BaseService implements TrackingCodeService {
    @Resource
    private SystemDictCache systemDictCache;
    @Resource
    private TrackingCodeMapper trackingCodeMapper;
    @Resource
    private TrackingProductSupplierMapper trackingProductSupplierMapper;
    @Resource
    private TrackingProductMapper trackingProductMapper;
    /**
     * 【查询所有溯源防伪码】溯源防伪码
     * @param req
     * @return
     */
    @DataScopeFilter
    @Override
    public ServiceResult<PageResult<List<QueryTrackingCodePageRes>>> queryTrackingCodePageResList(QueryTrackingCodePageReq req) {
        PageHelperUtil.orderByAndStartPage(req, "createTime desc, trackingCodeId desc");
        List<QueryTrackingCodePageRes> list = trackingCodeMapper.queryTrackingCodePageResList(req);
        for (QueryTrackingCodePageRes res:list){
            SystemDict dictStatus = systemDictCache.getSystemDictByDictCode(res.getStatusCode());
            res.setStatusName(dictStatus.getDictName());
            res.setStatusColor(dictStatus.getDictColor());
        }
        return PageHelperUtil.returnServiceResult(req, list);
    }


    /**
     * 【保存】批量溯源防伪码
     * @param req
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ServiceResult batchSaveTrackingCode(BatchSaveTrackingCodeReq req) {
        //当前登录用户
        UserTokenInfoVo userTokenInfoVo = getCurrentLoginUserInfoDTO();
        //当前租户id
        String tenantId = userTokenInfoVo.getTenantId();
        //检查产品id是否存在
        checkTrackingProductId(req.getProductId(),tenantId);
        //检查供货商是否存在
        checkTrackingSupplierId(req.getSupplierId(),tenantId);
        //当前时间
        Date date = new Date();
        //待入库集合对象
        List<TrackingCode> trackingCodeList = new ArrayList<>();
        //批量生成
        for (int i=0;i<req.getBatchTotal();i++){
            //防伪码id
            String trackingCodeId = UUIDUtils.getUUID32();
            //构建对象
            TrackingCode trackingCode = new TrackingCode();
            trackingCode.setTrackingCodeId(trackingCodeId);
            trackingCode.setTrackingCode(UUIDUtils.getSequenceNo());
            trackingCode.setTrackingNumber(UUIDUtils.getSequenceNo());
            trackingCode.setTrackingBatch(req.getTrackingBatch());
            trackingCode.setTransportCode(req.getTransportCode());
            trackingCode.setStatusCode(req.getStatusCode());
            trackingCode.setProductId(req.getProductId());
            trackingCode.setSupplierId(req.getSupplierId());
            trackingCode.setCreateTime(date);
            trackingCode.setUpdateTime(date);
            trackingCode.setCreateUserId(userTokenInfoVo.getUserId());
            trackingCode.setUpdateUserId(userTokenInfoVo.getUserId());
            trackingCode.setCreateDeptId(userTokenInfoVo.getCreateDeptId());
            trackingCode.setTenantId(tenantId);
            //加入到集合
            trackingCodeList.add(trackingCode);
        }
        //批量插入
        if (!trackingCodeList.isEmpty()){
            trackingCodeMapper.batchInsertListUseAllCols(trackingCodeList);
        }
        List<String> idList = trackingCodeList.stream().map(TrackingCode::getTrackingCodeId).collect(Collectors.toList());
        return ServiceResult.ok(idList.toString());
    }

    /**
     * 【保存】溯源防伪码
     * @param req
     * @return
     */
    @Override
    public ServiceResult saveTrackingCode(SaveTrackingCodeReq req) {
        //当前登录用户
        UserTokenInfoVo userTokenInfoVo = getCurrentLoginUserInfoDTO();
        //当前租户id
        String tenantId = userTokenInfoVo.getTenantId();
        //检查防伪码是否存在
        checkTrackingCode(req.getTrackingCode(),tenantId);
        //检查产品id是否存在
        checkTrackingProductId(req.getProductId(),tenantId);
        //检查供货商是否存在
        checkTrackingSupplierId(req.getSupplierId(),tenantId);
        //防伪码id
        String trackingCodeId = UUIDUtils.getUUID32();
        //当前时间
        Date date = new Date();
        //构建对象
        TrackingCode trackingCode = new TrackingCode();
        trackingCode.setTrackingCodeId(trackingCodeId);
        trackingCode.setTrackingNumber(UUIDUtils.getSequenceNo());
        trackingCode.setTrackingCode(req.getTrackingCode());
        trackingCode.setTrackingBatch(req.getTrackingBatch());
        trackingCode.setTransportCode(req.getTransportCode());
        trackingCode.setStatusCode(req.getStatusCode());
        trackingCode.setProductId(req.getProductId());
        trackingCode.setSupplierId(req.getSupplierId());
        trackingCode.setCreateTime(date);
        trackingCode.setUpdateTime(date);
        trackingCode.setCreateUserId(userTokenInfoVo.getUserId());
        trackingCode.setUpdateUserId(userTokenInfoVo.getUserId());
        trackingCode.setCreateDeptId(userTokenInfoVo.getCreateDeptId());
        trackingCode.setTenantId(tenantId);
        trackingCodeMapper.insertSelective(trackingCode);
        return ServiceResult.ok(trackingCodeId);
    }

    /**
     * 【修改】溯源防伪码
     * @param req
     * @return
     */
    @Override
    public ServiceResult updateTrackingCode(UpdateTrackingCodeReq req) {
        //防伪码id
        String trackingCodeId = req.getTrackingCodeId();
        TrackingCode trackingCodeOld = trackingCodeMapper.selectByPrimaryKey(trackingCodeId);
        if (trackingCodeOld==null){
            return ServiceResult.fail(ErrorCodes.PARAM_ERROR);
        }
        //当前租户id
        String tenantId = trackingCodeOld.getTenantId();
        //检查产品id是否存在
        checkTrackingProductId(req.getProductId(),tenantId);
        //检查供货商是否存在
        checkTrackingSupplierId(req.getSupplierId(),tenantId);
        //当前时间
        Date date = new Date();
        //构建对象
        TrackingCode trackingCode = new TrackingCode();
        trackingCode.setTrackingCodeId(trackingCodeId);
        trackingCode.setTrackingBatch(req.getTrackingBatch());
        trackingCode.setTransportCode(req.getTransportCode());
        trackingCode.setStatusCode(req.getStatusCode());
        trackingCode.setProductId(req.getProductId());
        trackingCode.setSupplierId(req.getSupplierId());
        trackingCode.setUpdateTime(date);
        trackingCode.setUpdateUserId(getCurrentLoginUserId());
        trackingCodeMapper.updateByPrimaryKeySelective(trackingCode);
        return ServiceResult.ok(trackingCodeId);
    }

    /**
     * 【删除】根据防伪码ID删除防伪码
     * @param req
     * @return
     */
    @Override
    public ServiceResult deleteTrackingCodeByTrackingCodeId(TrackingCodeIdReq req) {
        //防伪码id
        String trackingCodeId = req.getTrackingCodeId();
        TrackingCode trackingCode = trackingCodeMapper.selectByPrimaryKey(trackingCodeId);
        if (trackingCode==null){
            return ServiceResult.fail(ErrorCodes.PARAM_ERROR);
        }
        //防伪码删除
        trackingCodeMapper.deleteByPrimaryKey(trackingCodeId);
        return ServiceResult.ok(trackingCodeId);
    }


    /**
     * 【私有方法，辅助其他接口方法使用】 检查当前租户下面防伪码是否存在
     */
    private void checkTrackingCode(String trackingCode,String tenantId) {
        if (StringUtils.isBlank(trackingCode)||StringUtils.isBlank(tenantId)){
            throw new DuoJuHeException(ErrorCodes.TRACKING_CODE_EXIST);
        }
        Example example = new Example(TrackingCode.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("trackingCode", trackingCode);
        criteria.andEqualTo("tenantId", tenantId);
        if(trackingCodeMapper.selectByExample(example).size()>0){
            throw new DuoJuHeException(ErrorCodes.TRACKING_CODE_EXIST);
        }
    }

    /**
     * 【私有方法，辅助其他接口方法使用】 检查产品是否存在
     */
    private void checkTrackingProductId(String productId,String tenantId) {
        if (StringUtils.isBlank(productId)||StringUtils.isBlank(tenantId)){
            throw new DuoJuHeException(ErrorCodes.TRACKING_PRODUCT_NOT_EXIST);
        }
        TrackingProduct product = trackingProductMapper.selectByPrimaryKey(productId);
        if(product==null){
            throw new DuoJuHeException(ErrorCodes.TRACKING_PRODUCT_NOT_EXIST);
        }
        if (!tenantId.equals(product.getTenantId())){
            throw new DuoJuHeException(ErrorCodes.TRACKING_PRODUCT_NOT_EXIST);
        }
    }

    /**
     * 【私有方法，辅助其他接口方法使用】 检查供货商是否存在
     */
    private void checkTrackingSupplierId(String supplierId,String tenantId) {
        if (StringUtils.isBlank(supplierId)||StringUtils.isBlank(tenantId)){
            throw new DuoJuHeException(ErrorCodes.TRACKING_PRODUCT_SUPPLIER_NOT_EXIST);
        }
        TrackingProductSupplier productSupplier = trackingProductSupplierMapper.selectByPrimaryKey(supplierId);
        if(productSupplier==null || !SystemEnum.STATUS.NORMAL.getKey().equals(productSupplier.getStatusCode())){
            throw new DuoJuHeException(ErrorCodes.TRACKING_PRODUCT_SUPPLIER_NOT_EXIST);
        }
        if (!tenantId.equals(productSupplier.getTenantId())){
            throw new DuoJuHeException(ErrorCodes.TRACKING_PRODUCT_SUPPLIER_NOT_EXIST);
        }
    }
}
